package com.ibeeking.found.upms.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.upms.b.rest.service.*;
import com.ibeeking.found.upms.service.common.bo.CpPermissionBO;
import com.ibeeking.found.upms.service.common.bo.CpRolePermissionBO;
import com.ibeeking.found.upms.service.common.bo.CpUserRoleBO;
import com.ibeeking.found.upms.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.upms.service.common.dos.CpTpPermissionDO;
import com.ibeeking.found.upms.service.common.dos.CpTpPermissionGroupDO;
import com.ibeeking.found.upms.service.common.param.CpTpPermissionGroupParam;
import com.ibeeking.found.upms.service.common.vo.CpTpPermissionGroupVO;
import com.ibeeking.found.upms.service.common.vo.CurrentPermissionVO;
import com.ibeeking.found.upms.service.common.vo.PermissionVO;
import com.ibeeking.found.upms.service.mapper.CpTpPermissionGroupMapper;
import com.ibeeking.found.upms.service.mapper.CpTpPermissionMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName CsPermissionServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-04-28 12:56
 **/
@Service
public class CpTpPermissionGroupServiceImpl implements ICpTpPermissionGroupService {

    @Resource
    private CpTpPermissionGroupMapper cpTpPermissionGroupMapper;
    @Resource
    private CpTpPermissionMapper cpTpPermissionMapper;
    @Resource
    private ICpUserRoleService userRoleServiceImpl;
    @Resource
    private ICpRoleService roleServiceImpl;
    @Resource
    private ICpTpPermissionService cpTpPermissionServiceImpl;
    @Resource
    private ICpTpRolePermissionService tpRolePermissionServiceImpl;
    @Resource
    private RedisUtils redisUtils;

    @Override
    public List<CpTpPermissionGroupVO> queryEffective() {
        List<CpTpPermissionGroupDO> cpPermissionDos = cpTpPermissionGroupMapper.selectList(Wrappers.emptyWrapper());
        if (Collections3.isEmpty(cpPermissionDos)) {
            return Collections3.emptyList();
        }

        return JsonUtils.jsonToList(cpPermissionDos, CpTpPermissionGroupVO.class);
    }

    @Override
    public List<CpTpPermissionGroupVO> queryEffectiveGroupWithPermission() {
        Map<Long, List<PermissionVO>> groupPermissionMap = null;
        List<CpTpPermissionDO> cpTpAllPermissionDOS = cpTpPermissionMapper.selectList(Wrappers.emptyWrapper());
        if (Collections3.isNotEmpty(cpTpAllPermissionDOS)) {
            List<PermissionVO> cpTpAllPermissionVOS = JsonUtils.jsonToList(cpTpAllPermissionDOS, PermissionVO.class);
            groupPermissionMap = cpTpAllPermissionVOS.stream().collect(Collectors.groupingBy(PermissionVO::getParentId));
        }
        List<CpTpPermissionGroupDO> cpTpPermissionGroupDOS = cpTpPermissionGroupMapper.selectList(Wrappers.emptyWrapper());
        if (Collections3.isEmpty(cpTpPermissionGroupDOS)) {
            return Collections3.emptyList();
        }
        List<CpTpPermissionGroupVO> result = JsonUtils.jsonToList(cpTpPermissionGroupDOS, CpTpPermissionGroupVO.class);
        if(groupPermissionMap !=null && groupPermissionMap.size() >0) {
            for (CpTpPermissionGroupVO ss : result) {
                ss.setAppList(groupPermissionMap.get(ss.getId()) != null ? groupPermissionMap.get(ss.getId()) : null);
            }
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(CpTpPermissionGroupParam param) {
        if(StringUtils.isNotEmpty(param.getName())) {
            CpTpPermissionGroupDO checkPermissionDO = cpTpPermissionGroupMapper.selectOne(new LambdaQueryWrapper<CpTpPermissionGroupDO>()
                    .eq(CpTpPermissionGroupDO::getName, param.getName()));
            if(checkPermissionDO !=null) throw new BusinessException("已存在同名的标签组，请修改");
        }
        CpTpPermissionGroupDO permissionDO = BeanUtil.convertBean(param, CpTpPermissionGroupDO.class);
        permissionDO.setId(IdGenerator.getId());
        permissionDO.setCreateTime(LocalDateTime.now());
        permissionDO.setCreateBy(UserUtils.getUserId());
        return cpTpPermissionGroupMapper.insert(permissionDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(CpTpPermissionGroupParam param) {
        CpTpPermissionGroupDO permissionDO = BeanUtil.convertBean(param, CpTpPermissionGroupDO.class);
        permissionDO.setCreateTime(LocalDateTime.now());
        permissionDO.setCreateBy(UserUtils.getUserId());
        return cpTpPermissionGroupMapper.updateById(permissionDO) > 0;
    }

    @Override
    public CpTpPermissionGroupVO view(Long id) {
        CpTpPermissionGroupDO checkPermissionDO = cpTpPermissionGroupMapper.selectById(id);
        return BeanUtil.convertBean(checkPermissionDO, CpTpPermissionGroupVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        CpTpPermissionGroupDO checkPermissionDO = cpTpPermissionGroupMapper.selectById(id);
        if (null == checkPermissionDO) throw new BusinessException("功能模块板不存在");
        if(cpTpPermissionMapper.selectCount(new LambdaQueryWrapper<CpTpPermissionDO>().eq(CpTpPermissionDO::getParentId, id)) > 0){
            throw new BusinessException("该分组下有应用，请删除应用后再删除");
        }
        return cpTpPermissionGroupMapper.deleteById(id) > 0;
    }

}
